﻿using System.Security.Cryptography;
using System.Text;

namespace Aurora.Security.SHA
{
    public static class SHA256Extensions
    {
        /// <summary>
        /// 检查SHA256是否匹配
        /// </summary>
        /// <param name="input">用来比较的明文</param>
        /// <param name="hash">密文</param>
        /// <returns></returns>
        public static bool CompareSHA256Hash(this string input, string hash)
        {
            using SHA256 sha256Hash = SHA256.Create();
            var hashOfInput = GetSHA256Hash(sha256Hash, input);
            var comparer = StringComparer.OrdinalIgnoreCase;

            if (0 == comparer.Compare(hashOfInput, hash))
                return true;
            return false;
        }
        /// <summary>
        /// Generate SHA256 hash value
        /// </summary>
        /// <param name="input">Draft string value.</param>
        /// <returns></returns>
        public static string ToSHA256String(this string input)
        {
            using SHA256 sha256Hash = SHA256.Create();
            // Hash the input.
            string hashOfInput = GetSHA256Hash(sha256Hash, input);
            return hashOfInput;
        }

        public static string ToHMACSHA256String(this string value, string salt)
        {
            var bytes = Encoding.Default.GetBytes(value);
            var saltBytes = Encoding.Default.GetBytes(salt);
            var hasher = new HMACSHA256(saltBytes);
            var valueHash = hasher.ComputeHash(bytes);
            var result = string.Join("", valueHash.ToList().Select(b => b.ToString("x2")).ToArray());
            return result;
        }

        private static string GetSHA256Hash(SHA256 sha256Hash, string input)
        {
            var bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
            var sb = new StringBuilder();
            foreach (var item in bytes)
                sb.Append(item.ToString("x2"));

            return sb.ToString();
        }

        public static string GetSHA256WithRSAString(this string value, string privateKey)
        {
            if (string.IsNullOrEmpty(value))
            {
                throw new ArgumentNullException(nameof(value));
            }

            if (string.IsNullOrEmpty(privateKey))
            {
                throw new ArgumentNullException(nameof(privateKey));
            }

            using var rsa = System.Security.Cryptography.RSA.Create();
            rsa.ImportRSAPrivateKey(Convert.FromBase64String(privateKey), out var _);
            return Convert.ToBase64String(rsa.SignData(Encoding.UTF8.GetBytes(value), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1));
        }

    }
}